package api

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"net/http"

	"openzbox.com/frame/echo"
)

type LouKouDataT struct {
	HPressIn        float32 `json:"press_water_in_h"`  //进水压力
	HPressOut       float32 `json:"press_water_out_h"` //回水压力
	HWaterIn        float32 `json:"water_temp_in_h"`   //进水温度
	HWaterOut       float32 `json:"water_temp_out_h"`  //回水温度
	HCumulativeHeat float32 `json:"cumulative_heat_h"` //累积热量
	HHeatPower      float32 `json:"heat_power_h"`      //热功率
	HCumulativeFlow float32 `json:"cumulative_flow_h"` //累积流量
	HFlowRate       float32 `json:"flow_rate_h"`       //瞬时流量
	HKaiDu          float32 `json:"kai_du_h"`          //当前阀门开度
	HPressDiffer    float32 `json:"press_differ_h"`    //压差

	LPressIn        float32 `json:"press_water_in_l"`  //进水压力
	LPressOut       float32 `json:"press_water_out_l"` //回水压力
	LWaterIn        float32 `json:"water_temp_in_l"`   //进水温度
	LWaterOut       float32 `json:"water_temp_out_l"`  //回水温度
	LCumulativeHeat float32 `json:"cumulative_heat_l"` //累积热量
	LHeatPower      float32 `json:"heat_power_l"`      //热功率
	LCumulativeFlow float32 `json:"cumulative_flow_l"` //累积流量
	LFlowRate       float32 `json:"flow_rate_l"`       //瞬时流量
	LKaiDu          float32 `json:"kai_du_l"`          //当前阀门开度
	LPressDiffer    float32 `json:"press_differ_l"`    //压差

	Signl          uint8   `json:"signl"`             //信号值
	OnLine         uint8   `json:"on_line"`           //在线标志
	TotalEleEnergy float32 `json:"total_elec_energy"` //正向有功总电能
	Date           string  `json:"date"`              //日期
	Time           string  `json:"time"`              //时间
}

type HeatConfigT struct {
	HeatMeterType uint8  `json:"type"` //热量表型号{"0:CJ188", "1:en1413.", "2:modbus",
	HeatMeterAddr string `json:"addr"` //热量表地址"AAAAAAAAAAAAAAAAAA"
}

type ComConfigT struct {
	Baud   uint32 `json:"baud"`   //{"波特率",{"0:600", "1:1200", "2:2400", "3:4800", "4:9600", "5:19200", "6:38400", "7:57600", "8:115200"}},
	Parity uint8  `json:"parity"` //{"效验位", {"0:无效验", "1:偶效验", "2:奇效验", ""}
}

type PidConfigT struct {
	En   uint8 `json:"en_mode"` //0:自动  1:手动  2:远程
	Type uint8 `json:"type"`    //0-依据温度进行控制；1-依据瞬时热量进行控制；2-依据瞬时流量进行控制
	Min  uint8 `json:"min"`     //0-100,单位1%
	Max  uint8 `json:"max"`     //0-100,单位1%

	Ki      uint8  `json:"ki"`       //比例系数(控制周期,1-255,单位10S)  控制周期
	Kp      uint8  `json:"kp"`       //积分系数(步进,1-20,单位1%)
	Kd      uint16 `json:"kd"`       //微分系数(阈值,0-255,单位0.01) 阈值，允许的误差值，单位0.01
	TempSet uint16 `json:"temp_set"` //设定值(单位0.01)
}

type LouKouConfigT struct {
	AcquisitionPeriod uint16      `json:"acquisition_period"` //采集周期
	ReportingPeriod   uint16      `json:"reporting_period"`   //上报周期
	DevID             string      `json:"dev_id"`             //"装置ID",			"+DEVID=",
	DesClnId          string      `json:"des_cln_id"`         //"DES客户端的身份码",	"+DESCLNID=",
	Heat1Info         HeatConfigT `json:"heat1info"`
	Heat2Info         HeatConfigT `json:"heat2info"`
	Com1Info          ComConfigT  `json:"com1"`
	Com2Info          ComConfigT  `json:"com2"`
	PID1Info          PidConfigT  `json:"pid1"`
	PID2Info          PidConfigT  `json:"pid2"`
}
type LouKouPIDConfigT struct {
	PIDEN0      int    `json:"PIDEN0"`
	PIDEN1      int    `json:"PIDEN1"`
	HEATTYPE0   int    `json:"HEATTYPE0"`
	HEATTYPE1   int    `json:"HEATTYPE1"`
	HEATADDR0   string `json:"HEATADDR0"`
	HEATADDR1   string `json:"HEATADDR1"`
	PIDKI0      int    `json:"PIDKI0"`
	PIDKI1      int    `json:"PIDKI1"`
	PIDKP0      int    `json:"PIDKP0"`
	PIDKP1      int    `json:"PIDKP1"`
	PIDKD0      int    `json:"PIDKD0"`
	PIDKD1      int    `json:"PIDKD1"`
	PIDMIN0     int    `json:"PIDMIN0"`
	PIDMIN1     int    `json:"PIDMIN1"`
	PIDMAX0     int    `json:"PIDMAX0"`
	PIDMAX1     int    `json:"PIDMAX1"`
	PIDTEMPSET0 int    `json:"PIDTEMPSET0"`
	PIDTEMPSET1 int    `json:"PIDTEMPSET1"`
	TPITV       uint16 `json:"TPITV"`
	SPITV       uint16 `json:"SPITV"`
	DEVID       string `json:"DEVID"`
	DESCLNID    string `json:"DESCLNID"`
}

var LoukouData LouKouDataT
var LoukouConfig LouKouConfigT
var McuData McuDataT

func McuTimeData(c echo.Context) error {
	info := McuData
	fmt.Println(info)
	return c.JSON(http.StatusOK, info)
}

func LouKouRealTimeData(c echo.Context) error {
	info := getLouKouData()
	fmt.Println(info)
	return c.JSON(http.StatusOK, info)
}

func LouKouConfig(c echo.Context) error {
	info := getLouKouConfig()
	fmt.Println(info)
	return c.JSON(http.StatusOK, info)
}

func getLouKouData() (info LouKouDataT) {

	//info.HPressIn = 23.6        //进水压力
	//info.HPressOut = 23.6       //回水压力
	//info.HWaterIn = 23.6        //进水温度
	//info.HWaterOut = 23.6       //回水温度
	//info.HCumulativeHeat = 23.6 //累积热量
	//info.HHeatPower = 23.6      //热功率
	//info.HCumulativeFlow = 23.6 //累积流量
	//info.HFlowRate = 23.6       //瞬时流量
	//info.HKaiDu = 23.6          //当前阀门开度
	//info.HPressDiffer = 23.6    //压差
	//
	//info.LPressIn = 23.6        //进水压力
	//info.LPressOut = 23.6       //回水压力
	//info.LWaterIn = 23.6        //进水温度
	//info.LWaterOut = 23.6       //回水温度
	//info.LCumulativeHeat = 23.6 //累积热量
	//info.LHeatPower = 23.6      //热功率
	//info.LCumulativeFlow = 23.6 //累积流量
	//info.LFlowRate = 23.6       //瞬时流量
	//info.LKaiDu = 23.6          //当前阀门开度
	//info.LPressDiffer = 23.6    //压差
	//
	//info.Signl = 28              //信号值
	//info.OnLine = 1              //在线标志
	//info.TotalEleEnergy = 1223.6 //正向有功总电能
	//info.Date = "2023-02-22"     //日期
	//info.Time = "18:00:01"       //日期

	return LoukouData
}

func getLouKouConfig() (info LouKouConfigT) {

	//info.PIDEN0 = 1
	//info.PIDEN1 = 2
	//info.HEATTYPE0 = 1
	//info.HEATTYPE1 = 2
	//info.HEATADDR0 = "AAAAAAAAAAAAAAAAAA"
	//info.HEATADDR1 = "11AAAAAAAAAAAAAAAA"
	//info.PIDKI0 = 31
	//info.PIDKI1 = 32
	//info.PIDKP0 = 31
	//info.PIDKP1 = 32
	//info.PIDKD0 = 31
	//info.PIDKD1 = 32
	//info.PIDMIN0 = 31
	//info.PIDMIN1 = 32
	//info.PIDMAX0 = 31
	//info.PIDMAX1 = 32
	//info.PIDTEMPSET0 = 81
	//info.PIDTEMPSET1 = 82
	//info.TPITV = 60
	//info.SPITV = 300
	//info.DEVID = "1"
	//info.DESCLNID = "123456"

	info.Com1Info.Baud = 2
	info.Com2Info.Baud = 2
	info.Com2Info.Parity = 1
	info.Com2Info.Parity = 1
	info.PID1Info.En = 2
	info.PID2Info.En = 2
	info.Heat1Info.HeatMeterAddr = "AAAAAAAAAAAAAAAAAA"
	info.Heat2Info.HeatMeterAddr = "AAAAAAAAAAAAAAAAAA"

	//info.HPressIn = 23.6        //进水压力
	//info.HPressOut = 23.6       //回水压力
	//info.HWaterIn = 23.6        //进水温度
	//info.HWaterOut = 23.6       //回水温度
	//info.HCumulativeHeat = 23.6 //累积热量
	//info.HHeatPower = 23.6      //热功率
	//info.HCumulativeFlow = 23.6 //累积流量
	//info.HFlowRate = 23.6       //瞬时流量
	//info.HKaiDu = 23.6          //当前阀门开度
	//info.HPressDiffer = 23.6    //压差
	//
	//info.LPressIn = 23.6        //进水压力
	//info.LPressOut = 23.6       //回水压力
	//info.LWaterIn = 23.6        //进水温度
	//info.LWaterOut = 23.6       //回水温度
	//info.LCumulativeHeat = 23.6 //累积热量
	//info.LHeatPower = 23.6      //热功率
	//info.LCumulativeFlow = 23.6 //累积流量
	//info.LFlowRate = 23.6       //瞬时流量
	//info.LKaiDu = 23.6          //当前阀门开度
	//info.LPressDiffer = 23.6    //压差
	//
	//info.Signl = 28              //信号值
	//info.OnLine = 1              //在线标志
	//info.TotalEleEnergy = 1223.6 //正向有功总电能
	//info.Date = "2023-02-22"     //日期
	//info.Time = "18:00:01"       //日期

	return info
}

func TCP_Client_Thd() {

	tcpAddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:40005")
	if err != nil {
		log.Println("Fatal error")
	}
	conn, err := net.DialTCP("tcp", nil, tcpAddr)

	if err != nil {
		log.Println("Fatal error")
	} else {
		log.Println("connection success")
	}

	//for _, value := range work_list
	{

		loukou_config := getLouKouConfig()
		loukou_data := getLouKouData()

		loukou_json, err := json.Marshal(loukou_data)
		if err != nil {
			log.Println("error", err)
		}
		conn.Write([]byte(loukou_json))

		loukou_config_json, err := json.Marshal(loukou_config)
		if err != nil {
			log.Println("error", err)
		}
		conn.Write([]byte(loukou_config_json))

		mcu_data_json, err := json.Marshal(McuData)
		if err != nil {
			log.Println("error", err)
		}
		conn.Write([]byte(mcu_data_json))

		read_buf := make([]byte, 2048)

		for {
			n, err := conn.Read(read_buf)

			if err != nil {
				log.Fatal(err)
			}
			//fmt.Println(buffer[:n])
			//log.Println(n)
			fmt.Println("-------------------------------------------")

			//// 方式一：序列化成map，经常使用
			//anyMap := make(map[string]string)
			//if err := json.Unmarshal([]byte(buffer[:n]), &anyMap); err != nil {
			//	panic(err)
			//}
			//log.Println("Unmarshal to map result:", anyMap)
			//ageVal, ok := anyMap["Age"]
			//if ok {
			//	age, _ := strconv.ParseFloat(ageVal, 32)
			//	log.Println(ageVal)
			//	log.Println(age)
			//}

			// 方式二：反序列化成对象，经常使用
			err = json.Unmarshal(read_buf[:n], &loukou_data)
			if err != nil {
				fmt.Println("json unmarshal error:", err)
			} else {
				log.Println("loukou_data.HCumulativeHeat", loukou_data.HCumulativeHeat)
				log.Println("loukou_data.HCumulativeFlow", loukou_data.HCumulativeFlow)
				log.Println("loukou_data.HPressIn", loukou_data.HPressIn)
				log.Println("loukou_data.Date", loukou_data.Date)
			}

			fmt.Println("***************************************")

			// 方式三：不反序列化，只读取单个key，经常使用。适合特别复杂的json字符串，或者有多种if else结构的场景
			//userName := gjson.Get(jsonStr, "userName")
			//nickName := gjson.Get(jsonStr, "nick_name")
			//age := gjson.Get(jsonStr, "info.age").Int()

			// 取得extra数组0位置的对象
			//address1 := gjson.Get(jsonStr, "extra").Array()[1]
			//log.Println("get raw value by key:", userName, nickName, age, address1.Get("address"))

			//decoder, err := json.Marshal(buffer[:n]) //解析流

			//err = json.Unmarshal(buffer[:n], &work_result)
			//
			//age := gjson.Get(work_result, "Age")
			//fmt.Println("Age:", age)
			//fmt.Println("decoder:", decoder)
			//conn.Write([]byte(""))
		}
	}

	log.Println("send over")
	conn.Close()
}

func tcp_server_process(conn net.Conn) {
	//连接用完一定要关闭：
	defer conn.Close()
	read_buf := make([]byte, 1024)

	for {
		//创建一个切片，准备：将读取的数据放入切片：

		//从conn连接中读取数据：
		n, err := conn.Read(read_buf)
		if err != nil {
			return
		}
		//将读取内容在服务器端输出：
		//fmt.Println(string(read_buf[0:n]))

		// 方式二：反序列化成对象
		err = json.Unmarshal(read_buf[:n], &LoukouData)
		if err != nil {
			fmt.Println("json unmarshal error:", err)
		} else {
			log.Println("LoukouData.HCumulativeHeat", LoukouData.HCumulativeHeat)
			log.Println("LoukouData.HCumulativeFlow", LoukouData.HCumulativeFlow)
			log.Println("LoukouData.HPressIn", LoukouData.HPressIn)
		}

		err = json.Unmarshal(read_buf[:n], &LoukouConfig)
		if err != nil {
			fmt.Println("json unmarshal error:", err)
		} else {

			log.Println("loukou_config.DEVID :", LoukouConfig.DevID)
			log.Println("loukou_config.DESCLNID :", LoukouConfig.DesClnId)

		}

		fmt.Println("***************************************")
	}
}
func TCP_Server_Thd() {
	//打印：
	fmt.Println("服务器端启动了。。")
	//进行监听：需要指定服务器端TCP协议，服务器端的IP+PORT
	listen, err := net.Listen("tcp", "127.0.0.1:8888")
	if err != nil { //监听失败
		fmt.Println("监听失败，err:", err)
		return
	}
	//监听成功以后：
	//循环等待客户端的链接：
	for {
		conn, err2 := listen.Accept()
		if err2 != nil { //客户端的等待失败
			fmt.Println("客户端的等待失败,err2:", err2)
		} else {
			//连接成功：
			fmt.Printf("等待链接成功，con=%v ，接收到的客户端信息：%v \n", conn, conn.RemoteAddr().String())
		}
		//准备一个协程，协程处理客户端服务请求：
		go tcp_server_process(conn) //不同的客户端的请求，连接conn不一样的
	}
}
